/**
 * Created by jinxs on 14-8-11.
 */
(function ($) {
    /**
     * 缓存名称
     * @type {string}
     * @private
     */
    var _cacheName = 'uiNumberbox';
    /**
     * @name uiNumberbox
     * @class 数字输入框组件，只能输入数字，字符自动过滤掉。<br/>
     * @constructor uiNumberbox
     * @description 构造函数.
     * @param options 组件配置参数：{}
     * @example
     * $('numberbox').uiNumberbox({decimalPrecision:3});
     */
    $.fn.uiNumberbox = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.uiNumberbox.methods[options](this, param);
        }
        return this.each(function(){
            var me = $(this);
            var cache = me.data(_cacheName);

            options = options || {};
            if (cache) {
                $.extend(cache.options, options);
            } else {
                me.data(_cacheName, {
                    options: $.extend({}, $.fn.uiNumberbox.defaults, me.parseUIConfig(), options),
                    character: '',
                    allowed: ''
                });
            }
            _init(me);
        });
    };
    /**
     * 方法
     * @lends uiNumberbox.prototype
     */
    $.fn.uiNumberbox.methods = {
        /**
         * @summary 启用组件。
         * @name uiNumberbox#enable
         * @function
         * @example
         * $('#input').uiNumberbox("enable")
         */
        enable: function (target) {
            _enable(target);
            return target;
        },
        /**
         * @summary 禁用组件。
         * @name uiNumberbox#disable
         * @function
         * @example
         * $('#input').uiNumberbox("disable")
         */
        disable: function (target) {
            _disable(target);
            return target;
        }
    };
    /**
     * 默认配置
     * @lends uiNumberbox.prototype
     */
    $.fn.uiNumberbox.defaults =
    {
        /**
         * @summary 是否允许输入小数。
         * @default true
         * @type Boolean
         * @example
         * $('#input').uiNumberbox({allowDecimals:true});
         */
        allowDecimals: true,  //是否允许输入小数
        /**
         * @summary 是否允许输入负数。
         * @default true
         * @type Boolean
         * @example
         * $('#input').uiNumberbox({allowNegative:true});
         */
        allowNegative: true,  //是否允许输入负数
        /**
         * @summary 精确到小数点后几位。
         * @default 2
         * @type Number
         * @example
         * $('#input').uiNumberbox({decimalPrecision:2});
         */
        decimalPrecision: 2, //精确到小数点后几位
        /**
         * @summary 是否禁用组件。
         * @default false
         * @type Boolean
         * @example
         * $('#input').uiNumberbox({disabled:true});
         */
        disabled: false,
        /**
         * @summary 在输入框失去焦点时触发的方法。
         * @event
         * @param value 当前输入框的值
         * @param event jQuery.Event对象
         * @default emptyFn
         * @example
         * $('#input').uiNumberbox({onBlur:function(value,event){alert(value);}});
         */
        onBlur: function (value) {
        },
        /**
         * @summary 是否只读。
         * @default false
         * @type Boolean
         * @example
         * $('#input').uiNumberbox({readOnly:true});
         */
        readOnly: false
    };
//////--------------------------------内部方法------------------------------
    /**
     * 创建按钮
     * @param target 目标对象
     */
    var _init = function (target) {
        var options = $.data(target[0], _cacheName).options;
        options.id = options.id || target[0].id;
        target.attr("id", options.id);

        if (typeof options.disabled !== "boolean") {
            options.disabled = target.attr("disabled");
        }

        if (options.readOnly) {
            target.attr("readonly", "readonly");
        }
        _buildAllowChars(target);
        _create(target);
        if (options.disabled) {
            _disable(target);
        } else {
            _enable(target);
        }
        return target;
    };
    // 设置小数精度
    var _fixPrecision = function (value, c, p) {
        var v = value.indexOf(".");
        if (isNaN(value) && value != ".") {
            for (; isNaN(value);) {
                value = value.substring(0, value.length - 1);
            }
        }
        if (!p.allowNegative && value.indexOf("-") != -1) {
            var array = value.split("-");
            value = array.join("");
        }
        if (!p.allowDecimals && v != -1 || value.charAt(value.length - 1) === '.') {
            return value.substring(0, v);
        }
        if (v != -1) {
            value = value.substring(0, v + p.decimalPrecision + 1);
        }
        return value.length > 0 ? parseFloat(value) : "";
    };
    var _create = function (target) {
        var options = $.data(target[0], _cacheName).options;
        target.addClass("ui_numberbox")
            .css("ime-mode", "disabled");

        target.keypress(function (e) {
            if (e.which == null && (e.charCode != null || e.keyCode != null)) {
                e.which = e.charCode != null ? e.charCode : e.keyCode;
            }
            var k = e.which;
            if (k === 8 || (k == 46 && e.button == -1) || k === 0) {
                return;
            }
            var character = String.fromCharCode(k);
            $.data(target[0], _cacheName).character = character;
            var allowed = $.data(target[0], _cacheName).allowed;
            if (allowed.indexOf(character) === -1 || ($(this).val().indexOf("-") !== -1 && character == "-")
                || ($(this).val().indexOf(".") !== -1 && character == ".")) {
                e.preventDefault();
            }
        }).focus(function () {
                target.addClass('ui-focus');
            }).blur(function (e) {
                target.removeClass('ui-focus');
                var character = $.data(target[0], _cacheName).character;
                target[0].value = _fixPrecision(this.value, character, options);
                target.trigger("onBlur", e, this.value);
            }).keydown(function (e) {
                _checkLast(target);

                //Chrome并不支持css属性ime-mode,无法阻止拼音输入，但当使用输入法时，事件的e.which===229恒成立.
                if (229 === e.which) {
                    e.preventDefault();
                }
            }).keyup(function (e) {//在Chrome中文输入法下，输入  ，。等字符不会触发input框的keypress事件
                _checkLast(target);
            }).bind('cut paste', function (e) {
                return false;
            });
    };
    var _checkLast = function (target) {
        var v = target[0].value,
            len = v.length;
        if (v && $.data(target[0], _cacheName).allowed.indexOf(v.charAt(len - 1)) === -1
            || v.indexOf('.') != v.lastIndexOf('.')
            || v.indexOf('-') != v.lastIndexOf('-')) {
            target[0].value = v = v.substring(0, (len--) - 1);
        }
    };

    var _buildAllowChars = function (target) {
        var options = $.data(target[0], _cacheName).options;
        var allowed = "0123456789";
        // 允许输入的字符
        if (options.allowDecimals) {
            allowed = allowed + ".";
        }
        if (options.allowNegative) {
            allowed = allowed + "-";
        }
        if (options.readOnly) {
            allowed = "";
        }
        $.data(target[0], _cacheName).allowed = allowed;
    };
    var _disable = function (target) {
        target.attr("disabled", true)
            .addClass("ui-disabled");
    };
    var _enable = function (target) {
        target.attr("disabled", false)
            .removeClass("ui-disabled");
    };
})(jQuery);